package com.iretailer.report.easyexcel.serivce;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iretailer.report.easyexcel.data.CompanyData;
import com.iretailer.report.mapper.BusinessTimeMapper;
import com.iretailer.report.mapper.CompaniesMapper;
import com.iretailer.report.mapper.MallsMapper;
import com.iretailer.report.model.*;
import com.iretailer.report.service.CategoriesService;
import com.iretailer.report.service.UserMallService;
import com.iretailer.report.util.GetId;
import com.iretailer.report.util.SecurityUserUtil;
import com.iretailer.report.util.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: xjw
 * @Date: 2020/3/17 13:50
 * @Description:
 */
@Component
public class ImportCompany {
    @Autowired
    private CompaniesMapper companiesMapper;
    @Autowired
    private MallsMapper mallsMapper;
    @Autowired
    private UserMallService userMallService;
    @Autowired
    private CategoriesService categoriesService;
    @Autowired
    private BusinessTimeMapper businessTimeMapper;

    @Transactional(propagation = Propagation.REQUIRED)
    public void excelAnalysis(List<CompanyData> data) throws Exception {
        if (data != null && data.size() > 0) {
            Categories importBasicData = categoriesService.selectCategoryByKeyName("ImportBasicData");
            if (importBasicData == null) {
                throw new Exception("ImportBasicData Categories is null");
            }
            List<Categories> categories = categoriesService.selectCategoryByParentId(importBasicData.getId());
            Map<String, Categories> categoriesMap = categories.stream().collect(Collectors.toMap(Categories::getKeyName, a -> a));
             User user = SecurityUserUtil.currentUser(null);
            for (CompanyData c : data) {

                Companies companies = companiesMapper.selectOne(new QueryWrapper<Companies>().lambda().eq(Companies::getName, c.getCompanyName()));
                if (companies == null) {
                    // 还没有存在同一名称的公司
                    companies = insertCompany(c,user);
                }
                Malls findMall = mallsMapper.selectOne(new QueryWrapper<Malls>().lambda().eq(Malls::getName, c.getMallName()));
                if (findMall == null) {

                    Malls m = insertMall(c, companies.getId(), categoriesMap);
                    BusinessTimes b = businessTime(c, companies.getId(), categoriesMap);
                    businessTimeMapper.insertBusinessTimeMalls(b.getId(), Arrays.asList(m.getId()));
                    if (!user.getRoleId().equals("-")) {
                        userMallService.saveOrUpdate(new UserMall(user.getId(), m.getId(), 1));
                    }
                } else {
                    throw new Exception("MallName :[" + c.getMallName() + "]already exists");
                }
            }
        }
    }

    private Companies insertCompany(CompanyData companyData,User user) {
        Companies companies = new Companies();
        companies.setId(GetId.UUID());
        companies.setName(companyData.getCompanyName());
        companies.setCompanyCode(companyData.getCompanyCode());
        companies.setParentId(user.getCompanyId());
        companies.setCreateTime(LocalDateTime.now());
        companies.setCreateUser(user.getUserCode());
        companies.setStatus(1);
        companiesMapper.insert(companies);

        return companies;
    }

    private Malls insertMall(CompanyData c, String companyId, Map<String, Categories> categoriesMap) {
        // 默认 Mall是没有的，如果名称相同则会抛出异常
        Malls m = new Malls();
        m.setId(GetId.UUID());
        m.setEnabled(1);
        // 公司名称
        m.setCompanyId(companyId);
        m.setName(c.getMallName());
        m.setMallCode(c.getMallCode());
        m.setCreateTime(LocalDateTime.now());
        m.setContractStartDate(TimeUtil.localDate_format(c.getContractStartDate()));
        m.setContractEndDate(TimeUtil.localDate_format(c.getContractEndDate()));
        Categories province = categoriesMap.get("Province");
        // 省/直辖市
        if (province != null) {
            m.setProvinceId(province.getData());
        }
        // 城市
        Categories city = categoriesMap.get("City");
        if (city != null) {
            m.setCityId(city.getData());
        }
        // 时区
        Categories timezone = categoriesMap.get("DefaultTimeZone");
        if (timezone != null) {
            m.setTimeZone(timezone.getData());
        } else {
            m.setTimeZone("Etc/GMT-8");
        }
        m.setRanked(0);
        m.setOperationAcreage(0);
        m.setClerkNumber(0);
        mallsMapper.insert(m);
        return m;
    }

    private BusinessTimes businessTime(CompanyData c, String companyId, Map<String, Categories> categoriesMap) {
        // 营业时间设置
        Categories timeType = categoriesService.selectCategoryByKeyName("OrdinaryType");
        BusinessTimes b = new BusinessTimes();
        b.setId(GetId.UUID());
        b.setCompanyId(companyId);
        b.setTimeType(timeType.getId());
        b.setTimeTypeName(timeType.getName());
        b.setWeekdays("Mon,Tue,Wed,Thu,Fri,Sat,Sun");
        b.setStartDate(c.getContractStartDate());
        b.setEndDate(c.getContractEndDate());
        Categories startTime = categoriesMap.get("StartTime");
        if (startTime != null) {
            b.setStartTime(TimeUtil.parse_LocalTime(startTime.getData()));
        } else {
            b.setStartTime(LocalTime.of(10, 0, 0));
        }
        Categories endTime = categoriesMap.get("EndTime");
        if (endTime != null) {
            b.setEndTime(TimeUtil.parse_LocalTime(endTime.getData()));
        } else {
            b.setEndTime(LocalTime.of(22, 0, 0));
        }
        businessTimeMapper.insert(b);
        return b;
    }
}
